<?php

class Epic_File_Resize
{
	private $_image;
    private $_width;
    private $_height;
    private $_type;
	private $_imageResized;
	private $_newImageName;
	private $_path;

	function __construct($filePath)
	{
		list($this->_width, $this->_height, $this->_type) = getimagesize($filePath);
		$this->_image = $this->openImage($filePath);
		
		$this->_path = str_replace(basename($filePath), '', $filePath);
	}

	private function openImage($filePath)
	{	
		switch ($this->_type) {
			case 1:
				$img = @imagecreatefromgif($filePath);
				break;
			case 2:
				$img = @imagecreatefromjpeg($filePath);
				break;
			case 3:
				$img = @imagecreatefrompng($filePath);
				break;
			default:
				$img = NULL;
				break;
		}
		return $img;
	}

	public function resizeImage($newWidth, $newHeight, $option="crop")
	{
		$optionArray = $this->getDimensions($newWidth, $newHeight, $option);

		$optimalWidth  = $optionArray['optimalWidth'];
		$optimalHeight = $optionArray['optimalHeight'];

		// *** create image canvas of x, y size
		$this->_imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
		imagecopyresampled($this->_imageResized, $this->_image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->_width, $this->_height);

//		// *** if option is 'crop', then crop too
//		if ($option == 'crop') {
//			$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
//		}
	}

	private function getDimensions($newWidth, $newHeight, $option)
	{

	   switch ($option)
		{
			case 'exact':
				$optimalWidth  = $newWidth;
				$optimalHeight = $newHeight;
				break;
			case 'fixedheight': 
				$optimalWidth = $this->getSizeByFixedHeight($newHeight);
				$optimalHeight= $newHeight;
				break;
			case 'fixedwidth':
				$optimalWidth = $newWidth;
				$optimalHeight= $this->getSizeByFixedWidth($newWidth);
				break;
//			case 'auto':
//				$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
//				$optimalWidth = $optionArray['optimalWidth'];
//				$optimalHeight = $optionArray['optimalHeight'];
//				break;
			case 'crop':	// Chính xác kích thước đưa vào, không biến dạng ảnh
				$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
				$optimalWidth = $optionArray['optimalWidth'];
				$optimalHeight = $optionArray['optimalHeight'];
				break;
		}
		return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
	}

	/**
	 * Chiều cao chính xác theo giá trị đưa vào, chiều rộng tùy chỉnh
	 * 
	 * @param int $newHeight
	 * @return int
	 */
	private function getSizeByFixedHeight($newHeight)
	{
		$ratio = $this->_width / $this->_height;
		$newWidth = $newHeight * $ratio;
		return $newWidth;
	}

	/**
	 * Chiều rộng chính xác theo giá trị đưa vào, chiều cao tùy chỉnh
	 * 
	 * @param int $newWidth
	 * @return int
	 */
	private function getSizeByFixedWidth($newWidth)
	{
		$ratio = $this->_height / $this->_width;
		$newHeight = $newWidth * $ratio;
		return $newHeight;
	}
	
	/**
	 * 
	 * @param int $newWidth
	 * @param int $newHeight
	 * @return array
	 */
	private function getSizeByAuto($newWidth, $newHeight)
	{
		if ($this->_height < $this->_width) {
			$optimalWidth  = $newWidth;
			$optimalHeight = $this->getSizeByFixedWidth($newWidth);
		}
		elseif ($this->_height > $this->_width) {
			$optimalWidth  = $this->getSizeByFixedHeight($newHeight);
			$optimalHeight = $newHeight;
		} else {
			if ($newHeight < $newWidth) {
				$optimalWidth = $newWidth;
				$optimalHeight= $this->getSizeByFixedWidth($newWidth);
			} else if ($newHeight > $newWidth) {
				$optimalWidth = $this->getSizeByFixedHeight($newHeight);
				$optimalHeight= $newHeight;
			} else {
				$optimalWidth = $newWidth;
				$optimalHeight= $newHeight;
			}
		}

		return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
	}

//	private function getOptimalCrop($newWidth, $newHeight)
//	{
//
//		$heightRatio = $this->_height / $newHeight;
//		$widthRatio  = $this->_width  /  $newWidth;
//
//		if ($heightRatio < $widthRatio) {
//			$optimalRatio = $heightRatio;
//		} else {
//			$optimalRatio = $widthRatio;
//		}
//
//		$optimalHeight = $this->_height / $optimalRatio;
//		$optimalWidth  = $this->_width  / $optimalRatio;
//
//		return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
//	}

//	private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
//	{
//		// *** Find center - this will be used for the crop
//		$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
//		$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
//
//		$crop = $this->_imageResized;
//		//imagedestroy($this->_imageResized);
//
//		// *** Now crop from center to exact requested size
//		$this->_imageResized = imagecreatetruecolor($newWidth , $newHeight);
//		imagecopyresampled($this->_imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
//	}

	public function setNewImageName($newImageName)
	{
		$this->_newImageName = $newImageName;
	}

	public function saveImage($savePath = '', $imageQuality="100")
	{
		if($savePath == '') {
			$savePath = $this->_path . $this->_newImageName;
		} 
		$extension = strtolower(strrchr($savePath, '.'));
		
		switch($extension)
		{
			case '.jpg':
			case '.jpeg':
				if (imagetypes() & IMG_JPG)
					imagejpeg($this->_imageResized, $savePath, $imageQuality);
				break;
			case '.gif':
				if (imagetypes() & IMG_GIF)
					imagegif($this->_imageResized, $savePath);
				break;
			case '.png':
				// Scale quality from 0-100 to 0-9
				$scaleQuality = round(($imageQuality/100) * 9);
				// Invert quality setting as 0 is best, not 9
				$invertScaleQuality = 9 - $scaleQuality;
				if (imagetypes() & IMG_PNG)
					 imagepng($this->_imageResized, $savePath, $invertScaleQuality);
				break;
			default:
				break; // No extension - No save.
		}

		imagedestroy($this->_imageResized);
	}
}
